﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class USControlTimelines : Editor
{
    private static USTimelineBaseEditor defaultEditor = null;
    private static GUIStyle defaultFloatingBackground = GUIStyle.none;
    private static GUIStyle defaultTimelineBackground = GUIStyle.none;
    private static Texture dragAreaTexture = null;
    private static Vector2 dragStartPosition = Vector2.zero;
    private static bool hasStartedDrag = false;
    private static bool isBoxSelecting = false;
    private static bool isDragging = false;
    private static Transform mouseOverObject = null;
    private static USTimelineBase mouseOverTimeline = null;
    private static Rect selectionArea = new Rect();
    private static Rect timelineArea = new Rect();

    public static void Clean()
    {
        UnityEngine.Object.DestroyImmediate(defaultEditor);
    }

    public static void Display(float areaWidth, float areaHeight, float floatingWidth, float xScroll, USSequencer sequence)
    {
        GetDefaultStyles();
        PushObserverToTop(sequence);
        DisplayTimelineBackground(areaWidth, areaHeight, floatingWidth, sequence);
        DisplayTimelineContents(areaWidth, areaHeight, floatingWidth, xScroll, sequence);
        DisplayFloatingBackground(areaWidth, areaHeight, floatingWidth, sequence);
    }

    private static void DisplayFloatingBackground(float areaWidth, float areaHeight, float floatingWidth, USSequencer sequence)
    {
        Rect position = new Rect(0f, 0f, areaWidth, areaHeight);
        foreach (USTimelineContainer container in sequence.SortedTimelineContainers)
        {
            if (EditorTimelineData.Data.ContainsKey(container.transform))
            {
                EditorTimelineData data = EditorTimelineData.Data[container.transform];
                if (!USControl.ShowOnlyAnimated || data.hasAnimatedChildren)
                {
                    Rect rect2 = position;
                    rect2.x = 0f;
                    rect2.height = 17f;
                    rect2.width = floatingWidth;
                    GUI.Box(rect2, string.Empty, defaultTimelineBackground);
                    Rect thisArea = rect2;
                    thisArea.x += 15f;
                    thisArea.width -= thisArea.x;
                    if (thisArea.Contains(Event.current.mousePosition) && !IsBoxSelecting)
                    {
                        DefaultEditor.HandleFloatingInteraction(container.transform, thisArea);
                    }
                    Rect rect4 = rect2;
                    if (data.expandable)
                    {
                        EditorGUIUtility.LookLikeControls();
                        data.expanded = EditorGUI.Foldout(rect2, data.expanded, string.Empty);
                        EditorGUIUtility.LookLikeInspector();
                    }
                    container.RenameTimelineContainer();
                    string label = string.Empty;
                    label = container.name.Replace("的时间线", string.Empty);
                    if (label.Contains("的时间线"))
                    {
                        label = container.name.Replace("的时间线", string.Empty);
                    }
                    EditorGUI.LabelField(rect4, label);
                    position.y += 17f;
                    if (data.expanded)
                    {
                        foreach (USTimelineBase base2 in container.Timelines)
                        {
                            USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base2);
                            rect2 = position;
                            rect2.x = 0f;
                            rect2.height = key.MyArea.height;
                            rect2.width = floatingWidth;
                            GUI.Box(rect2, string.Empty, defaultTimelineBackground);
                            if (base2.AffectedObject == null)
                            {
                                GUI.Label(position, string.Empty);
                                position.y += key.MyArea.height;
                            }
                            else
                            {
                                Rect rect5 = rect2;
                                rect5.x += 35f;
                                rect5.width -= 35f;
                                if (rect5.Contains(Event.current.mousePosition) && !IsBoxSelecting)
                                {
                                    key.HandleFloatingInteraction(base2.transform, rect5);
                                }
                                key.OnFloatingContents(rect2);
                                position.y += key.MyArea.height;
                            }
                        }
                    }
                }
            }
        }
    }

    private static void DisplayTimelineBackground(float areaWidth, float areaHeight, float floatingWidth, USSequencer sequence)
    {
        Rect rect = new Rect(0f, 0f, areaWidth, areaHeight);
        foreach (USTimelineContainer container in sequence.SortedTimelineContainers)
        {
            if (EditorTimelineData.Data.ContainsKey(container.transform))
            {
                EditorTimelineData data = EditorTimelineData.Data[container.transform];
                if (!USControl.ShowOnlyAnimated || data.hasAnimatedChildren)
                {
                    Rect position = rect;
                    position.x = floatingWidth;
                    position.width -= floatingWidth;
                    position.height = 17f;
                    GUI.Box(position, string.Empty, defaultTimelineBackground);
                    rect.y += 17f;
                    if (data.expanded)
                    {
                        foreach (USTimelineBase base2 in container.Timelines)
                        {
                            USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base2);
                            position = rect;
                            position.x = floatingWidth;
                            position.width -= floatingWidth;
                            position.height = key.MyArea.height;
                            key.OnTimelineBackground(position);
                            if (position.Contains(Event.current.mousePosition))
                            {
                                if (base2 is USTimelineEvent)
                                {
                                    mouseOverTimeline = base2 as USTimelineEvent;
                                }
                            }
                            else if (base2 == mouseOverTimeline)
                            {
                                mouseOverTimeline = null;
                            }
                            rect.y += key.MyArea.height;
                        }
                    }
                }
            }
        }
    }

    private static void DisplayTimelineContents(float areaWidth, float areaHeight, float floatingWidth, float xScroll, USSequencer sequence)
    {
        timelineArea = new Rect(floatingWidth - xScroll, 0f, (areaWidth - floatingWidth) + xScroll, areaHeight);
        Rect position = new Rect(0f, 0f, timelineArea.width, timelineArea.height);
        position.width = USControl.convertTimeToEventPanePosition(sequence.Duration);
        GUILayout.BeginArea(timelineArea);
        foreach (USTimelineContainer container in sequence.SortedTimelineContainers)
        {
            if (EditorTimelineData.Data.ContainsKey(container.transform))
            {
                EditorTimelineData data = EditorTimelineData.Data[container.transform];
                if (!USControl.ShowOnlyAnimated || data.hasAnimatedChildren)
                {
                    USTimelineObserver observer = null;
                    foreach (USTimelineBase base2 in container.Timelines)
                    {
                        observer = base2 as USTimelineObserver;
                    }
                    if (observer != null)
                    {
                        string name = (Camera.main == null) ? "null" : Camera.main.name;
                        if ((observer.CurrentlyActiveKeyframe != null) && (observer.CurrentlyActiveKeyframe.camera != null))
                        {
                            name = observer.CurrentlyActiveKeyframe.camera.name;
                        }
                        Rect rect2 = position;
                        rect2.x += xScroll;
                        GUI.Label(rect2, "当前镜头 : " + name);
                    }
                    position.y += 17f;
                    if (data.expanded)
                    {
                        foreach (USTimelineBase base3 in container.Timelines)
                        {
                            USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base3);
                            if (!(base3 is USTimelineObserver) && (base3.AffectedObject == null))
                            {
                                GUI.Label(position, "受影响对象已经删除. 撤销删除，时间线就会重新出现");
                                position.y += key.MyArea.height;
                            }
                            else
                            {
                                key.OnTimelineContents(position);
                                position.y += key.MyArea.height;
                            }
                        }
                    }
                }
            }
        }
        GUILayout.EndArea();
    }

    private static void GetDefaultStyles()
    {
        if (dragAreaTexture == null)
        {
            dragAreaTexture = Resources.Load("DragAreaTexture", typeof(Texture)) as Texture;
        }
        if (defaultFloatingBackground == GUIStyle.none)
        {
            GUISkin uSeqSkin = USEditorUtility.USeqSkin;
            if (uSeqSkin != null)
            {
                defaultFloatingBackground = uSeqSkin.GetStyle("TimelineLeftPaneBackground");
            }
        }
        if (defaultTimelineBackground == GUIStyle.none)
        {
            GUISkin skin2 = USEditorUtility.USeqSkin;
            if (skin2 != null)
            {
                defaultTimelineBackground = skin2.GetStyle("TimelinePaneBackground");
            }
        }
    }

    public static float GetDisplayHeight(USSequencer sequence)
    {
        float num = 0f;
        foreach (USTimelineContainer container in sequence.SortedTimelineContainers)
        {
            if (EditorTimelineData.Data.ContainsKey(container.transform))
            {
                EditorTimelineData data = EditorTimelineData.Data[container.transform];
                if (!USControl.ShowOnlyAnimated || data.hasAnimatedChildren)
                {
                    num += 17f;
                    if (data.expanded)
                    {
                        foreach (USTimelineBase base2 in container.Timelines)
                        {
                            USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base2);
                            num += key.MyArea.height;
                        }
                    }
                }
            }
        }
        return num;
    }

    public static void HandleEvent(USSequencer sequence, EventType eventType, int button, Vector2 mousePosition)
    {
        Rect rectA = new Rect(mousePosition.x, mousePosition.y, 1f, 1f);
        if (isBoxSelecting && hasStartedDrag)
        {
            rectA = selectionArea;
        }
        List<UnityEngine.Object> selectedObjects = new List<UnityEngine.Object>();
        foreach (USTimelineContainer container in sequence.TimelineContainers)
        {
            EditorTimelineData data = EditorTimelineData.Data[container.transform];
            if (data.expanded)
            {
                foreach (USTimelineBase base2 in container.Timelines)
                {
                    USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base2);
                    Rect myArea = key.MyArea;
                    myArea.width += 50f;
                    if (USEditorUtility.DoRectsOverlap(rectA, myArea))
                    {
                        key.GetSelectableObjectUnderPos(ref selectedObjects, rectA);
                    }
                }
            }
        }
        switch (eventType)
        {
            case EventType.MouseDown:
                isDragging = false;
                isBoxSelecting = false;
                dragStartPosition = mousePosition;
                if ((USSelection.GetNumOfSelections() == 0) && (selectedObjects.Count == 0))
                {
                    isBoxSelecting = true;
                }
                if (selectedObjects.Count > 0)
                {
                    isDragging = true;
                }
                if ((!Event.current.command && !Event.current.control) && ((selectedObjects.Count == 0) || !USSelection.IsInUnitySelection(selectedObjects[0])))
                {
                    USSelection.ClearSelection();
                    Selection.objects = USSelection.Objects;
                }
                if (selectedObjects.Count > 0)
                {
                    if (Event.current.command || Event.current.control)
                    {
                        USSelection.ToggleAddSelection(selectedObjects[0]);
                    }
                    else if (!USSelection.IsInUnitySelection(selectedObjects[0]))
                    {
                        USSelection.ClearSelection();
                        USSelection.AddSelection(selectedObjects[0]);
                        Selection.objects = USSelection.Objects;
                    }
                }
                hasStartedDrag = false;
                if (button == 1)
                {
                    HandleEventRightClick(sequence, mousePosition);
                }
                return;

            case EventType.MouseUp:
                if (isDragging && !isBoxSelecting)
                {
                    foreach (USTimelineContainer container4 in sequence.TimelineContainers)
                    {
                        foreach (USTimelineBase base5 in container4.Timelines)
                        {
                            EditorTimelineObjectMap.GetKey(base5).OnDragEnd();
                        }
                    }
                }
                if ((!hasStartedDrag && !isBoxSelecting) && (USSelection.GetNumOfSelections() == 1))
                {
                    USInternalKeyframe keyframe = Selection.objects[0] as USInternalKeyframe;
                    if (keyframe != null)
                    {
                        USControl.SetTime(keyframe.Time, sequence);
                    }
                    USEventBase base6 = Selection.objects[0] as USEventBase;
                    if (base6 != null)
                    {
                        EditorGUIUtility.PingObject(base6.transform);
                        Selection.activeTransform = base6.transform;
                    }
                }
                isBoxSelecting = false;
                isDragging = false;
                return;

            case EventType.MouseMove:
                return;

            case EventType.MouseDrag:
                if (!hasStartedDrag)
                {
                    hasStartedDrag = true;
                    USSelection.StartDragSelection();
                    if (isBoxSelecting)
                    {
                        break;
                    }
                    foreach (USTimelineContainer container2 in sequence.TimelineContainers)
                    {
                        foreach (USTimelineBase base3 in container2.Timelines)
                        {
                            EditorTimelineObjectMap.GetKey(base3).OnDragStart();
                        }
                    }
                }
                break;

            default:
                return;
        }
        Vector2 delta = mousePosition - dragStartPosition;
        if (isDragging && !isBoxSelecting)
        {
            foreach (USTimelineContainer container3 in sequence.TimelineContainers)
            {
                foreach (USTimelineBase base4 in container3.Timelines)
                {
                    EditorTimelineObjectMap.GetKey(base4).OnDrag();
                }
            }
            USSelection.DragSelection(delta);
        }
        if (isBoxSelecting)
        {
            USSelection.ClearSelection();
            foreach (UnityEngine.Object obj2 in selectedObjects)
            {
                USSelection.AddSelection(obj2);
            }
            if (Selection.objects.Length != USSelection.GetNumOfSelections())
            {
                Selection.objects = USSelection.Objects;
            }
        }
    }

    public static void HandleEventRightClick(USSequencer sequence, Vector2 mousePosition)
    {
        GenericMenu contextMenu = new GenericMenu();
        if (USSelection.GetNumOfSelections() > 0)
        {
            contextMenu.AddItem(new GUIContent("删除"), false, new GenericMenu.MenuFunction2(USControlTimelines.ProcessDelete), sequence);
        }
        else
        {
            contextMenu.AddDisabledItem(new GUIContent("删除"));
        }
        foreach (USTimelineContainer container in sequence.TimelineContainers)
        {
            EditorTimelineData data = EditorTimelineData.Data[container.transform];
            if (data.expanded)
            {
                foreach (USTimelineBase base2 in container.Timelines)
                {
                    USTimelineBaseEditor key = EditorTimelineObjectMap.GetKey(base2);
                    if (key.MyArea.Contains(mousePosition))
                    {
                        key.AddRightClickOptions(contextMenu, mousePosition);
                    }
                }
            }
        }
        contextMenu.ShowAsContext();
    }

    public static void ProcessDelete(object obj)
    {
        USSequencer objectToUndo = obj as USSequencer;
        if (objectToUndo != null)
        {
            Undo.RegisterUndo(objectToUndo, "删除序列");
            foreach (USTimelineContainer container in objectToUndo.TimelineContainers)
            {
                foreach (USTimelineBase base2 in container.Timelines)
                {
                    EditorTimelineObjectMap.GetKey(base2).ProcessRemoveObject();
                }
            }
            USSelection.ClearSelection();
        }
    }

    private static void PushObserverToTop(USSequencer sequence)
    {
        foreach (USTimelineContainer container in sequence.SortedTimelineContainers)
        {
            foreach (USTimelineBase base2 in container.Timelines)
            {
                if (base2 is USTimelineObserver)
                {
                    container.Index = -1;
                }
            }
        }
    }

    private static USTimelineBaseEditor DefaultEditor
    {
        get
        {
            if (defaultEditor == null)
            {
                defaultEditor = ScriptableObject.CreateInstance<USTimelineBaseEditor>();
            }
            return defaultEditor;
        }
    }

    public static Vector2 DragStartPosition
    {
        get
        {
            return dragStartPosition;
        }
    }

    public static bool HasStartedDrag
    {
        get
        {
            return hasStartedDrag;
        }
    }

    public static bool IsBoxSelecting
    {
        get
        {
            return isBoxSelecting;
        }
    }

    public static Transform MouseOverObject
    {
        get
        {
            return mouseOverObject;
        }
        set
        {
            mouseOverObject = value;
        }
    }

    public static USTimelineBase MouseOverTimeline
    {
        get
        {
            return mouseOverTimeline;
        }
    }

    public static Rect SelectionArea
    {
        set
        {
            selectionArea = value;
        }
    }

    private class ContextData
    {
        public Transform currentSelection;
        public Transform mouseOver;
        public float time;
        public System.Type typeToCreate;
    }
}

